<!-- 绑定设备页 -->
<template>
	<view class="bind-container" :key="componentKey">
		<view class="desc">请选择以下方式进行绑定</view>

		<!-- 1) 蓝牙连接 -->
		<button class="bind-button" @click="onBluetoothConnect">
			通过蓝牙绑定
		</button>

		<!-- 2) 扫码连接按钮 -->
		<button class="bind-button" @click="onScanQRCodeConnect">
			扫描二维码绑定
		</button>

		<!-- 3) 手动连接按钮 -->
		<!-- <button class="bind-button" @click="onShowManualConnectPopup">
			手动绑定
		</button> -->

		<!-- 相机组件: 如果要实时扫描，可用 <camera> + 识别；或配合 wx.scanCode -->
		<!-- 这里保留 camera 仅示例 -->
		<!-- <view v-show="isShow" class="container">
			<camera id="camera" device-position="back" flash="off"></camera>
		</view> -->

		<!-- 手动连接弹框 -->
		<!-- <view v-if="showManualConnectPopup" class="name-edit-popup">
			<view class="name-edit-popup-content">
				<view class="popup-title">手动输入设备</view>

				<input class="name-input" v-model="deviceCode" placeholder="请输入设备编码" maxlength="30" />
				<input class="name-input" v-model="alarmName" placeholder="请输入闹钟名称" maxlength="30" />

				<view class="popup-actions">
					<button @click="onCancelNameEdit">取消</button>
					<button @click="onConfirmNameEdit">确定</button>
				</view>
			</view>
		</view> -->

		<!-- 蓝牙设备列表弹框 -->
		<view v-if="showBLEDevicesPopup" class="ble-popup-mask">
			<view class="ble-popup">
				<view class="popup-title">附近蓝牙设备</view>
				<scroll-view class="ble-device-list" scroll-y>
					<view class="ble-device-item" v-for="(dev, index) in bleDevices" :key="dev.deviceId"
						@click="onSelectBLEDevice(dev)">
						<view class="device-name">{{ dev.name || '未知设备' }}</view>
						<view class="device-id">{{ dev.deviceId }}</view>
						<view v-if="connectingDeviceId === dev.deviceId" class="connecting-tip">
							{{connectStatus}}
						</view>
					</view>
				</scroll-view>
				<view class="popup-actions">
					<button @click="onCancelBLEList">关闭</button>
				</view>
			</view>
		</view>

		<!-- 输入WIFI信息弹框 (在蓝牙连接后需要) -->
		<view v-if="showWiFiPopup" class="name-edit-popup">
			<view class="name-edit-popup-content">
				<view class="popup-title">配置设备Wi-Fi</view>

				<!-- 如果能拿到设备扫描的wifiList，可用 <picker> 显示下拉 -->
				<!-- <picker v-if="wifiList && wifiList.length" mode="selector" :range="wifiList"
					v-model="selectedWiFiIndex">
					<view class="wifi-picker">{{ wifiList[selectedWiFiIndex] || '选择Wi-Fi' }}</view>
				</picker> -->
				<!-- 否则让用户手动填 -->
				<!-- <input v-else class="name-input" v-model="wifiSSID" placeholder="请输入Wi-Fi名称(SSID)" /> -->
				<input class="name-input" v-model="wifiSSID" placeholder="请输入Wi-Fi名称(SSID)" />

				<input class="name-input" v-model="wifiPassword" placeholder="请输入Wi-Fi密码" />

				<view class="popup-actions">
					<button @click="onCancelWiFiConfig">取消</button>
					<button @click="onConfirmWiFiConfig">确定</button>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	import {
		addClock
	} from '@/src/api/clock.js'
	import {
		SERVICE_ID,
		CHARACTERISTIC_ID
	} from '@/src/config.js'
	export default {
		data() {
			return {
				openid: getApp().globalData.openid || uni.getStorageSync("openid"),
				isShow: false,
				componentKey: 1,
				connectStatus: '',
				connectingDeviceId: '',

				// 手动弹框
				showManualConnectPopup: false, // 控制手动连接弹框
				deviceCode: '', // 存放用户输入的设备编码
				alarmName: '', // 存放用户输入的闹钟名称

				// BLE设备
				showBLEDevicesPopup: false,
				bleDevices: [], // 搜索到的蓝牙设备列表
				deviceSearchTimeout: null, // 5秒检测不到设备

				// Wi-Fi配置
				showWiFiPopup: false,
				wifiList: [], // 如果设备能返回可选WiFi列表
				selectedWiFiIndex: 0,
				wifiSSID: '',
				wifiPassword: '',

				// 蓝牙信息
				deviceId: '', // 连接成功后的 deviceId
				serviceId: `${SERVICE_ID}`, // 服务ID
				characteristicId: `${CHARACTERISTIC_ID}`, // 特征值ID

				connectedDevices: [] // 存储已连接的设备信息
			}
		},
		methods: {
			/* ========== 1. 二维码扫描连接 ========== */
			async onScanQRCodeConnect() {
				// 微信小程序: wx.scanCode / uni.scanCode
				uni.scanCode({
					onlyFromCamera: true, // 可选
					success: async (res) => {
						console.log('扫码结果:', res);
						// 假设二维码里包含 deviceId
						// 也可能是 JSON 或 URL，需要你解析
						const deviceId = res.result // or parse ...
						// 弹框或直接发后端
						this.alarmName = ''
						this.deviceCode = deviceId
						// 这里也可直接 addClock 绑定
						// 也可跟手动一样，先让用户输入一个闹钟名称
						uni.showModal({
							title: '扫描成功',
							content: `已获取设备ID:${deviceId}, 是否绑定？`,
							success: async (modalRes) => {
								if (modalRes.confirm) {
									try {
										await this.bindDevice(deviceId, `闹钟${deviceId}`, 2)
										uni.showToast({
											title: '绑定成功',
											icon: 'success'
										})
									} catch (e) {
										uni.showToast({
											title: e.message || '绑定失败',
											icon: 'none'
										})
									}
								}
							}
						})
					},
					fail: (err) => {
						console.error('扫描失败:', err)
						uni.showToast({
							title: '扫描失败',
							icon: 'none'
						})
					}
				})
			},

			/* ========== 2. 手动连接 ========== */
			onShowManualConnectPopup() {
				this.showManualConnectPopup = true
			},
			onCancelNameEdit() {
				this.showManualConnectPopup = false
			},
			async onConfirmNameEdit() {
				// 手动输入 -> addClock
				try {
					await this.bindDevice(this.deviceCode, this.alarmName, 3)
					uni.showToast({
						title: '绑定成功',
						icon: 'success'
					})
					this.showManualConnectPopup = false
				} catch (e) {
					uni.showToast({
						title: e.message || '绑定失败',
						icon: 'none'
					})
				} finally {
					this.deviceCode = ''
					this.alarmName = ''
				}
			},

			/* ========== 3. 蓝牙连接 ========== */
			async onBluetoothConnect() {
				// 提示用户先检查是否打开定位(安卓需要定位权限才能搜到BLE)
				// 这里可先调 wx.getSetting / uni.getSetting 检查权限
				// 打开蓝牙
				uni.openBluetoothAdapter({
					success: () => {
						console.log('蓝牙适配器初始化成功')
						// 开始搜索
						this.startBLEDiscovery()
					},
					fail: (err) => {
						console.error('openBluetoothAdapter失败:', err)
						uni.showToast({
							title: '请检查蓝牙是否开启',
							icon: 'none'
						})
					}
				})
			},

			// 搜索附近蓝牙设备
			startBLEDiscovery() {
				// 清空旧数据
				this.bleDevices = []
				this.connectStatus = ''
				this.connectingDeviceId = ''

				// 开始搜索
				uni.startBluetoothDevicesDiscovery({
					// 限制只检索指定服务uuid数组的设备
					// services: [this.serviceId],
					// 是否允许重复上报同一设备。如果允许重复上报，则 uni.onBlueToothDeviceFound 方法会多次上报同一设备，但是 RSSI 值会有不同。
					allowDuplicatesKey: false,
					success: (res) => {
						console.log('开始搜索蓝牙设备...', res)
						// 监听发现设备
						uni.onBluetoothDeviceFound(this.onBLEDeviceFound)

						// 5秒后检测一下有没有发现设备
						this.deviceSearchTimeout = setTimeout(() => {
							if (this.bleDevices.length === 0) {
								uni.showModal({
									title: '提示',
									content: '未搜索到设备，请确认已打开蓝牙和定位',
									showCancel: false
								})
							}
						}, 5000)

						// 打开弹框
						this.showBLEDevicesPopup = true
					},
					fail: (err) => {
						console.error('搜索蓝牙设备失败', err)
						uni.showToast({
							title: '搜索蓝牙失败',
							icon: 'none'
						})
					}
				})
			},

			// 查找蓝牙设备
			onBLEDeviceFound(deviceRes) {
				let devs = deviceRes.devices || []
				devs.forEach(d => {
					if (!d.deviceId) return
					// 过滤空名字设备？可选
					// if (!d.name && !d.localName) return
					// 去重
					if (!this.bleDevices.find(x => x.deviceId === d.deviceId)) {
						d.name = d.name || d.localName || '未知设备'
						this.bleDevices.push(d)
					}
				})
			},

			// 选中设备
			onSelectBLEDevice(dev) {
				// 标记 正在连接
				this.connectStatus = '连接中...'
				this.connectingDeviceId = dev.deviceId
				// 停止搜索(可选)
				uni.stopBluetoothDevicesDiscovery()

				// deviceId不为null表示该设备已连接
				if (this.deviceId) {
					// 查询当前设备是否已连接
					uni.onBLEConnectionStateChange(function(res) {
						// 该方法回调中可以用于处理连接意外断开等异常情况
						console.log(
							`device ${res.deviceId} state has changed,=========================== connected: ${res.connected}`
						)
						var resDeviceId = `${res.deviceId}`
						var resContented = `${res.connected}`
						console.log(resContented)
						if (resContented == true) {
							uni.closeBLEConnection({
								resDeviceId,
								success(res) {
									console.log("断开蓝牙连接：", res)
								}
							})
						}
					});
				}

				// 真正连接
				uni.createBLEConnection({
					deviceId: dev.deviceId,
					success: (connRes) => {
						console.log('蓝牙连接成功 =>', connRes)
						// 连接成功后可弹出WiFi配置弹框
						this.deviceId = dev.deviceId
						this.showWiFiPopup = true
						// 设置蓝牙最大传输单元  需在 uni.createBLEConnection调用成功后调用，mtu 设置范围 (22,512)。安卓5.1以上有效。
						uni.setBLEMTU({
							deviceId: this.deviceId,
							mtu: 512
						});
					},
					fail: (err) => {
						console.error('蓝牙连接失败', err)
						uni.showToast({
							title: '设备连接失败，请稍后再试',
							icon: 'none'
						})
					}
				});
			},

			// 取消蓝牙连接
			onCancelBLEList() {
				this.showBLEDevicesPopup = false

				// 停止搜索 + 移除监听
				uni.stopBluetoothDevicesDiscovery()
				uni.offBluetoothDeviceFound(this.onBLEDeviceFound)
				if (this.deviceSearchTimeout) {
					clearTimeout(this.deviceSearchTimeout)
				}
				// 关闭蓝牙连接时关闭蓝牙适配器  关闭蓝牙模块。调用该方法将断开所有已建立的连接并释放系统资源。建议在使用蓝牙流程后，与 uni.openBluetoothAdapter 成对调用。
				uni.closeBluetoothAdapter({
					success(res) {
						console.log("关闭蓝牙适配器：", res)
					}
				})
			},

			// 配置WIFI信息
			onCancelWiFiConfig() {
				this.showWiFiPopup = false
				this.connectStatus = ''
				this.connectingDeviceId = ''

				// 查询当前设备是否已连接
				uni.onBLEConnectionStateChange(function(res) {
					// 该方法回调中可以用于处理连接意外断开等异常情况
					console.log(
						`device ${res.deviceId} state has changed,=========================== connected: ${res.connected}`
					)
					var resDeviceId = `${res.deviceId}`
					var resContented = `${res.connected}`
					console.log(resContented)
					if (resContented == true) {
						uni.closeBLEConnection({
							resDeviceId,
							success(res) {
								console.log("断开蓝牙连接：", res)
							}
						})
					}
				});
			},
			async onConfirmWiFiConfig() {
				// 这里拿到 wifiSSID, wifiPassword
				console.log('用户输入WiFi =>', this.wifiSSID, this.wifiPassword)

				// 把WIFI信息传给设备
				// 1) 将 wifiSSID + wifiPassword 拼成字符串，或 JSON, 或约定格式
				//    示例: "ssid=xxx;pwd=xxx"
				const sendStr = `ssid=${this.wifiSSID};pwd=${this.wifiPassword}`

				// 2) 转成 ArrayBuffer
				const buffer = this.stringToArrayBuffer(sendStr)

				// 3) 调用写特征值API
				console.log('设备信息 =>', this.deviceId, this.serviceId, this.characteristicId, buffer)
				uni.writeBLECharacteristicValue({
					deviceId: this.deviceId, // 你连接成功后的 deviceId
					serviceId: this.serviceId,
					characteristicId: this.characteristicId,
					value: buffer,
					writeType: 'writeNoResponse',
					success: (res) => {
						console.log('写入 WiFi 成功 =>', res)
						// 可以提示用户
						// uni.showToast({
						// 	title: 'Wi-Fi写入成功',
						// 	icon: 'success'
						// })
						// 4) 再去调用 bindDevice(…)
						// 绑定设备
						this.bindDevice2(this.deviceId, `闹钟${this.deviceId}`, 1).then(data => {
							console.log("bindDevice2.res : ", data)
							if (data.status == 200) {
								uni.showToast({
									title: '绑定成功',
									icon: 'success'
								})
								this.connectStatus = '已连接'
								this.connectingDeviceId = this.deviceId
							} else {
								uni.showToast({
									title: data.message || '绑定失败',
									icon: 'none'
								})
								this.connectStatus = ''
								this.connectingDeviceId = ''
							}
							this.showWiFiPopup = false
							this.deviceId = ''
							this.wifiSSID = ''
							this.wifiPassword = ''
							this.showBLEDevicesPopup = ''
						}).catch(error => {
							// 如果Promise被拒绝，这里的error就是reject传递的错误
							console.error(error);
							uni.showToast({
								title: '绑定失败',
								icon: 'none'
							})
							this.connectStatus = ''
							this.connectingDeviceId = ''
						});
					},
					fail: (err) => {
						console.error('写入WiFi失败 =>', err)
						uni.showToast({
							title: '写入WiFi失败，无法绑定，请重试',
							icon: 'none'
						})
						uni.onBLEConnectionStateChange(function(res) {
							// 该方法回调中可以用于处理连接意外断开等异常情况
							console.log(
								`device ${res.deviceId} state has changed,**************** connected: ${res.connected}`
							)
							var resDeviceId = `${res.deviceId}`
							var resContented = `${res.connected}`
							console.log(resContented)
							if (resContented == true) {
								uni.closeBLEConnection({
									resDeviceId,
									success(res) {
										console.log("断开蓝牙连接：", res)
									}
								})
							}
						});

						// 尝试重连
						// this.showReconnectButton(this.deviceId);
					},
					complete: () => {
						// 关闭弹框
						this.showWiFiPopup = false
						this.wifiSSID = ''
						this.wifiPassword = ''
						this.connectStatus = ''
						this.connectingDeviceId = ''
					}
				})
			},

			// 显示重新连接按钮
			showReconnectButton(deviceId) {
				wx.showModal({
					title: '设备连接失败',
					content: 'Wi-Fi数据发送失败，是否重试?',
					success: (res) => {
						if (res.confirm) {
							// 重新连接设备
							let device = {
								deviceId: deviceId
							}
							this.onSelectBLEDevice(device);
						}
					}
				});
			},

			// 把字符串转 ArrayBuffer
			stringToArrayBuffer(str) {
				let buffer = new ArrayBuffer(str.length)
				let dataView = new DataView(buffer)
				for (let i = 0; i < str.length; i++) {
					dataView.setUint8(i, str.charCodeAt(i))
				}
				return buffer
			},

			// 把设备+闹钟信息发后端
			async bindDevice(deviceId, alarmName, bindSource) {
				let paramObj = {
					openId: this.openid,
					deviceId,
					clockName: alarmName,
					bindSource: bindSource // 1.蓝牙 2.扫描二维码 3手动
				}
				const res = await addClock(paramObj)
				console.log('bindDevice =>', res)
				if (res.status != 200) {
					throw new Error(res.message)
				}
				// 绑定成功
				// 之后可 navigateBack 或别的逻辑
			},

			// 把设备+闹钟信息发后端
			async bindDevice2(deviceId, alarmName, bindSource) {
				let paramObj = {
					openId: this.openid,
					deviceId,
					clockName: alarmName,
					bindSource: bindSource // 1.蓝牙 2.扫描二维码 3手动
				}
				const res = await addClock(paramObj)
				console.log('bindDevice2 =>', res)
				return res;
				// 绑定成功
				// 之后可 navigateBack 或别的逻辑
			},

			// 连接成功后处理
			onBindSuccess(alarmName) {
				// 你可以在这里把新闹钟信息存储到本地或全局
				// const alarmList = uni.getStorageSync('alarmList') || []
				// const newAlarmId = Date.now()
				// alarmList.push({ id: newAlarmId, name: alarmName })
				// uni.setStorageSync('alarmList', alarmList)

				// 回退到闹钟列表页
				uni.navigateBack({
					delta: 1
				})
			}
		}
	}
</script>

<style>
	.bind-container {
		padding: 20px;
	}

	.desc {
		font-size: 14px;
		color: #666;
		margin-bottom: 20px;
	}

	.bind-button {
		display: block;
		background-color: #07c160;
		color: #fff;
		padding: 10px 20px;
		margin-bottom: 10px;
		border-radius: 4px;
		text-align: center;
		font-size: 16px;
	}

	/* 弹框公共样式 */
	.name-edit-popup {
		position: fixed;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.4);
		display: flex;
		justify-content: center;
		align-items: center;
		z-index: 9999;
	}

	.name-edit-popup-content {
		background: #fff;
		width: 80%;
		max-width: 400px;
		padding: 20px;
		border-radius: 6px;
		box-sizing: border-box;
		/* 包含内边距 */
	}

	.name-input {
		width: 100%;
		height: 40px;
		padding: 5px 10px;
		border: 1px solid #ccc;
		box-sizing: border-box;
		margin-bottom: 15px;
	}

	.popup-title {
		font-size: 16px;
		font-weight: bold;
		margin-bottom: 15px;
	}

	.popup-actions {
		display: flex;
		justify-content: flex-end;
		gap: 15px;
	}

	/* BLE 设备弹框 - 遮罩 */
	.ble-popup-mask {
		position: fixed;
		left: 0;
		right: 0;
		top: 0;
		bottom: 0;
		background-color: rgba(0, 0, 0, 0.6);
		z-index: 9999;
		display: flex;
		justify-content: center;
		align-items: center;
	}

	/* BLE 弹框主体 */
	.ble-popup {
		background: #fff;
		width: 80%;
		max-width: 450px;
		height: 66vh;
		/* 使用 max-height */
		display: flex;
		flex-direction: column;
		border-radius: 6px;
		padding: 15px;
		box-sizing: border-box;
		/* 包含内边距 */
	}

	.popup-title {
		font-size: 18px;
		font-weight: bold;
		margin-bottom: 10px;
	}

	.ble-device-list {
		flex: 1;
		margin-top: 10px;
		background-color: #f9f9f9;
		border-radius: 4px;
		padding: 5px;
		overflow-y: auto;
		/* 启用垂直滚动 */
		box-sizing: border-box;
		/* 包含内边距 */
	}

	.ble-device-item {
		background: #fff;
		border: 1px solid #eee;
		border-radius: 4px;
		margin-bottom: 8px;
		padding: 10px;
	}

	.device-name {
		font-weight: bold;
		color: #333;
	}

	.device-id {
		font-size: 12px;
		color: #999;
	}

	.connecting-tip {
		margin-top: 5px;
		font-size: 12px;
		color: #409eff;
	}
</style>